package com.test.jni.config;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * NativeLoader
 * 直接调用NativeLoader.loader( “native” );加载动态链接库
 *
 */
@Slf4j
public class NativeLoader {

    /**
     * 加载项目下的native文件，DLL或SO
     *
     * @param dirPath 需要扫描的文件路径，项目下的相对路径
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public synchronized static void loader(String dirPath) throws IOException, ClassNotFoundException {
        Enumeration<URL> dir = Thread.currentThread().getContextClassLoader().getResources(dirPath);
        // 获取操作系统类型
        String systemType = System.getProperty("os.name");
        //String systemArch = System.getProperty("os.arch");
        // 获取动态链接库后缀名
        String ext = (systemType.toLowerCase().indexOf("win") != -1) ? ".dll" : ".so";
        while (dir.hasMoreElements()) {
            URL url = dir.nextElement();
            File file = new File(url.getPath());
            loadFileNative(file, ext);
        }
    }

    private static void loadFileNative(File file, String ext) {
        if (null == file) {
            return;
        }
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (null != files) {
                for (File f : files) {
                    loadFileNative(f, ext);
                }
            }
        }
        if (file.canRead() && file.getName().endsWith(ext)) {
            try {
                System.load(file.getPath());
                log.info("==加载native文件 :" + file + "成功!!");
            } catch (UnsatisfiedLinkError e) {
                log.info("==加载native文件 :" + file + "失败!!请确认操作系统是X86还是X64!!!");
            }
        }
    }
}